﻿using System.Reflection;

namespace Foundation.Core
{
    public class SelectTypeFilter : ISelectTypeFilter
    {
        private readonly SelectFilterRegistrar _registrar;

        public SelectTypeFilter(SelectFilterRegistrar registrar)
        {
            this._registrar = registrar;
        }

        public virtual bool IsAllowType(Type type)
        {
            var filters = _registrar.GetAllowFilters();

            foreach (var factory in filters)
            {
                if (factory(type)) return true;
            }

            //枚举
            if (type.IsEnum) return !type.IsGenericTypeDefinition;

            return GetAttributeInfo(type) != null;
        }

        public virtual string CreateKey(Type type)
        {
            var factory = _registrar.FinTypeNameFactory(type);
            if (factory != null)
            {
                return factory(type);
            }

            var info = GetAttributeInfo(type);

            if (!(info?.Key).IsNullOrEmpty()) return info.Key;

            return type.FullName;
        }

        protected virtual FlagAttributeInfo GetAttributeInfo(Type type)
        {
            var attributes = type.GetCustomAttributes();

            foreach (var attr in attributes)
            {
                var t = attr.GetType();
                if (t.FullName.EndsWith("SelectItemsAttribute"))
                {
                    var key = string.Empty;
                    var kp = t.GetProperty("Key");

                    if (kp != null && kp.CanRead && kp.PropertyType == typeof(string))
                    {
                        key = kp.GetValue(attr) as string;

                        return new FlagAttributeInfo { Attibute = attr, Key = key };
                    }
                }
            }

            return null;
        }

        protected class FlagAttributeInfo
        {
            public Attribute Attibute { get; set; }

            public string Key { get; set; }
        }
    }
}
